//
// Copyright 2001-2004 Stottler Henke Associates, Inc.
// All Rights Reserved.
//////////////////////////////////////////////////////////////////////

package com.stottlerhenke.simbionic.engine.file;

import com.stottlerhenke.simbionic.engine.SB_SingletonBook;
import com.stottlerhenke.simbionic.engine.core.SB_BehaviorClass;
import com.stottlerhenke.simbionic.common.*;


/**
 * This class defines the format for behavior package specification 
 * files (ie bim files).
 */
public class SB_PackageSpec extends SB_Specification
{
	/**
	 * Constructor
	 * @param reader the stream reader from which to read the specification
	 * @param packageName the name of the package
	 */
	public SB_PackageSpec(SB_StreamReader reader,String packageName)
	{
		super(reader,packageName);
	}

	/**
	 * Reads the entire specification from the supplied stream.
	 * @param book container for all engine singletons
	 * @throws SB_FileException on failure
	 */
	public void read(SB_SingletonBook book) throws SB_FileException
	{
	  if (SIM_Constants.DEBUG_INFO_ON)
	  	book.getLogger().log("** Reading package spec '" + _specName + "'...");

		// verify a compatible sim-file format
		_reader.readSectionTag(SB_StreamReader.TAG_SIM_FORMAT);
		int formatVersion = _reader.readInt();
		if (!isCompatibleSpecFormat(formatVersion))
		{
			throw new SB_FileException("Incompatible sim file format: engine version " 
										+ SIM_Constants.SIM_FORMAT_MAX_VERSION + ", file version " + formatVersion);
		}

		// verify that this bim file goes with the current sim file
		_reader.readSectionTag(SB_StreamReader.TAG_SIM_FILENAME);
		String simName = _reader.readPString();
		if (simName.compareTo( book.getFileRegistry().getProjectFilename() ) != 0)
			throw new SB_FileException("Package file '" + _specName + "' [" + simName 
						+ "] doesn't match loaded project file '" + book.getFileRegistry().getProjectFilename() + "'");

		readBehaviors(book);

	  if (SIM_Constants.DEBUG_INFO_ON)
	  	book.getLogger().log("** Package spec file '" + _specName + "' loaded.",SB_Logger.INIT);
	}

	/**
	 * Loads behaviors from specification.
	 * @param book container for all engine singletons
	 * @throws SB_FileException on failure
	 */
	private void readBehaviors(SB_SingletonBook book) throws SB_FileException
	{
		_reader.readSectionTag(SB_StreamReader.TAG_BEHAVIORS_START);

		int numBehaviors = _reader.readInt();

		// read the behaviors one-by-one from the file
		SB_BehaviorClass behavior;
		for (int i=0; i < numBehaviors; i++)
		{
			// set the behavior's unique ID on creation
			behavior = new SB_BehaviorClass( book.getBehaviorRegistry().requestBehaviorId() );

			behavior.load(_reader, book);

			book.getBehaviorRegistry().addBehavior(behavior);
			book.getFileRegistry().associatePackage(_specName,behavior.getName());
		}
	}

}
